﻿using RpcCentral.Model;
using RpcCentral.Model.DB;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.IdGenerator;
using WeDonekRpc.Model;
using WeDonekRpc.SqlSugar;

namespace RpcCentral.DAL.Repository
{
    internal class RemoteServerDAL : IRemoteServerDAL
    {
        private readonly IRepository<RemoteServerConfig> _Db;
        public static readonly RpcServiceState[] _EnableState = new RpcServiceState[]
        {
            RpcServiceState.待启用,
            RpcServiceState.正常
        };
        public RemoteServerDAL (IRepository<RemoteServerConfig> db)
        {
            this._Db = db;
        }
        public long Add (RemoteServerConfig add)
        {
            add.Id = IdentityHelper.CreateId();
            this._Db.Insert(add);
            return add.Id;
        }
        public int GetVerNum (long id)
        {
            return this._Db.Get(a => a.Id == id, a => a.VerNum);
        }
        public RemoteServerModel GetRemoteServer (long id)
        {
            return this._Db.Get<RemoteServerModel>(a => a.Id == id);
        }
        public BasicServer[] GetRemoteServerConfig (long[] ids)
        {
            return this._Db.Gets<BasicServer>(a => ids.Contains(a.Id) && a.ServiceState == RpcServiceState.正常);
        }
        public long[] LoadServer (int serverIndex)
        {
            return this._Db.Gets(c => c.BindIndex == serverIndex && c.IsOnline && _EnableState.Contains(c.ServiceState), c => c.Id);
        }
        public void SetHoldRpcMerId (long serverId, long rpcMerId)
        {
            if (!this._Db.Update(new RemoteServerConfig
            {
                Id = serverId,
                HoldRpcMerId = rpcMerId
            }, new string[] {
                "ApiVer"
            }))
            {
                throw new ErrorException("rpc.server.apiver.set.fail");
            }
        }
        public void SetApiVer (long serverId, int ver)
        {
            if (!this._Db.Update(new RemoteServerConfig
            {
                Id = serverId,
                ApiVer = ver
            }, new string[] {
                "ApiVer"
            }))
            {
                throw new ErrorException("rpc.server.apiver.set.fail");
            }
        }
        public bool ServerOnline (long serverId, int serverIndex)
        {
            return this._Db.Update(a => new RemoteServerConfig
            {
                IsOnline = true,
                BindIndex = serverIndex
            }, a => a.Id == serverId && a.IsOnline == false);
        }
        public void SetConIp (long serverId, string conIp)
        {
            if (!this._Db.Update(new RemoteServerConfig
            {
                Id = serverId,
                ConIp = conIp
            }, new string[] {
                "ConIp"
            }))
            {
                throw new ErrorException("rpc.server.conIp.set.fail");
            }
        }
        public bool ServerOffline (long serverId, int serverIndex)
        {
            return this._Db.Update(a => new RemoteServerConfig
            {
                IsOnline = false,
                LastOffliceDate = HeartbeatTimeHelper.CurrentDate
            }, a => a.Id == serverId && a.IsOnline == true && a.BindIndex == serverIndex);
        }

        public long FindServiceId (long systemType, string mac, int serverIndex)
        {
            return this._Db.Get(c => c.SystemType == systemType && c.ServerMac == mac && c.ServerIndex == serverIndex, c => c.Id);
        }
        public long FindServiceId (long containerId)
        {
            return this._Db.Get(c => c.ContainerId == containerId, c => c.Id);
        }

    }
}
